package com.example.springredis;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.*;
import org.springframework.data.redis.support.collections.RedisCollection;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.xml.datatype.Duration;
import java.util.*;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("/redis")
public class RedisController {
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @RequestMapping("/general")
    public String generalTest() {
        System.out.println(stringRedisTemplate.keys("*"));
        System.out.println(stringRedisTemplate.expire("key1", 1, TimeUnit.MINUTES));
        System.out.println(stringRedisTemplate.delete("key2"));
        return "OK";
    }

    @RequestMapping("/string")
    public String stringDemo() {
        // 清空数据
        stringRedisTemplate.execute((RedisConnection connection) -> {
            connection.flushAll();
            return "OK";
        });
        // 添加数据
        ValueOperations<String, String> stringStringValueOperations = stringRedisTemplate.opsForValue();
        stringStringValueOperations.set("key1", "111");
        stringStringValueOperations.set("key2", "222");
        stringStringValueOperations.set("key3", "333");
        // 获取数据
        System.out.println(stringStringValueOperations.get("key1"));
        System.out.println(stringStringValueOperations.get("key4"));
        // 一次添加多个数据
        Map<String, String> hash = new HashMap<>();
        hash.put("aa", "a");
        hash.put("bb", "b");
        hash.put("cc", "c");
        stringStringValueOperations.multiSet(hash);
//        stringRedisTemplate.keys("*");
        // 一次获取多个数据
        List<String> list = new ArrayList<>(Arrays.asList("aa", "key1", "bb", "key10"));
        System.out.println(stringStringValueOperations.multiGet(list));
        // append
        System.out.println("key1: " + stringStringValueOperations.get("key1"));
        stringStringValueOperations.append("key1", "22222");
        System.out.println("key1: " + stringStringValueOperations.get("key1"));
        // 计数相关命令
        System.out.println("key2: " + stringStringValueOperations.get("key2"));
        System.out.println(stringStringValueOperations.increment("key2", 10));
        System.out.println("key2: " + stringStringValueOperations.get("key2"));
        return "OK";
    }

    @RequestMapping("/hash")
    public String hashTest() {
        stringRedisTemplate.execute((RedisConnection collection) -> {
            collection.flushAll();
            return "OK";
        });
        // 存储元素
        HashOperations<String, Object, Object> stringObjectObjectHashOperations = stringRedisTemplate.opsForHash();
        HashMap<String, String> hash = new HashMap<>();
        hash.put("h1", "1");
        hash.put("h2", "2");

        // 一次存多个元素
        stringObjectObjectHashOperations.putAll("key2", hash);
        stringObjectObjectHashOperations.put("key1", "f1", "11");

        // 取出元素
        System.out.println(stringObjectObjectHashOperations.get("key1", "h1"));
        System.out.println(stringObjectObjectHashOperations.get("key1", "f1"));

        // 获取 key 中所有元素
        System.out.println(stringObjectObjectHashOperations.entries("key2"));
        // 删除元素
        System.out.println(stringObjectObjectHashOperations.delete("key2", "h1", "h2", "h3"));
        System.out.println(stringObjectObjectHashOperations.entries("key2"));
        return "OK";
    }

    @RequestMapping("/list")
    public String ListTest() {
        stringRedisTemplate.execute((RedisConnection connection) -> {
            connection.flushAll();
            return "OK";
        });
        ListOperations<String, String> stringStringListOperations = stringRedisTemplate.opsForList();
        // 存储元素(头插)
        stringStringListOperations.leftPushAll("key1", "1", "2", "3");
        // 获取元素
        System.out.println(stringStringListOperations.leftPop("key1"));
        System.out.println(stringStringListOperations.leftPop("key1"));
        // 存储元素(尾插)
        stringStringListOperations.rightPush("key2", "1");
        stringStringListOperations.rightPush("key2", "2");
        stringStringListOperations.rightPush("key2", "3");
        stringStringListOperations.rightPush("key2", "4");
        // 获取元素
        System.out.println(stringStringListOperations.rightPop("key2"));
        System.out.println(stringStringListOperations.rightPop("key2"));
        return "OK";
    }

    @RequestMapping("/set")
    public String setTest() {
        stringRedisTemplate.execute((RedisConnection connection) -> {
            connection.flushAll();
            return "OK";
        });
        SetOperations<String, String> stringStringSetOperations = stringRedisTemplate.opsForSet();
        // 存储元素
        stringStringSetOperations.add("key", "1", "2", "3", "4", "5");
        // 判断元素是否存在
        System.out.println(stringStringSetOperations.isMember("key", "1"));
        System.out.println(stringStringSetOperations.isMember("key", "hey"));
        System.out.println("---------------------------");
        // 获取元素个数
        System.out.println(stringStringSetOperations.size("key"));
        System.out.println("-------------------------------");
        // 弹出元素
        System.out.println(stringStringSetOperations.pop("key", 2));
        System.out.println("-------------------------------");
        // 移动元素
        System.out.println(stringStringSetOperations.move("key", "3", "key2"));
        // 求交集、并集 和 差集
        stringStringSetOperations.add("key1", "1", "2", "3", "4", "5");
        stringStringSetOperations.add("key2", "2", "4", "6", "8", "10");
        System.out.println("交集: " + stringStringSetOperations.intersect("key1", "key2"));
        System.out.println("并集: " + stringStringSetOperations.union("key1", "key2"));
        System.out.println("差集: " + stringStringSetOperations.difference("key1", "key2"));
        return "OK";
    }
    @RequestMapping("/zset")
    public String ZsetTest() {
        stringRedisTemplate.execute((RedisConnection connection) -> {
            connection.flushAll();
            return "OK";
        });
        ZSetOperations<String, String> stringStringZSetOperations = stringRedisTemplate.opsForZSet();
        // 添加元素
        stringStringZSetOperations.add("key1", "zhangsan", 10.2);
        stringStringZSetOperations.add("key1", "lisi", 20.2);
        stringStringZSetOperations.add("key1", "wangwu", 45.2);
        stringStringZSetOperations.add("key1", "zhaoliu", 30.2);
        stringStringZSetOperations.add("key1", "aa", 60.2);
        // 获取元素个数
        System.out.println(stringStringZSetOperations.zCard("key1"));
        // 指定区间内元素个数
        System.out.println(stringStringZSetOperations.count("key1", 20, 40));
        // 返回指定区间内元素
        System.out.println(stringStringZSetOperations.range("key1", 1, 4));
        // 倒序返回
        System.out.println(stringStringZSetOperations.reverseRange("key1", 1, 4));
        // 弹出最大元素
        System.out.println(stringStringZSetOperations.popMax("key1"));
        // 弹出最小元素
        System.out.println(stringStringZSetOperations.popMin("key1"));
        return "OK";
    }
}
